package com.chaosj.skill.enhance

import net.sf.cglib.proxy.Enhancer
import net.sf.cglib.proxy.MethodInterceptor
import net.sf.cglib.proxy.MethodProxy

import java.lang.reflect.Method

/**
 * @Description:
 * @author: caoyangjie
 * @date: 2019年12月2019/12/10日 17:17
 * @Copyright: © 赢时胜
 */
class CglibEnhancer {
    static void main(args){
        // 代理实现类
        HelloWorld hw = new HelloWorld()
        hw.flag = true
        HelloWorld helloWorld = new ProxyFactory<HelloWorld>().createProxy(hw)
        println(helloWorld.sayHello(false))
        // 代理接口类
//        Protocol protocol = new ProxyFactory<Protocol>().createProxy(Protocol.class)
//        println(protocol.hello())
    }

    static class HelloWorld{
        boolean flag = false

        String sayHello(boolean say){
            if( !say && flag ){
                return "回答错误"
            }
            return "回答正确"
        }
    }

    static class ProxyFactory<T> implements MethodInterceptor{
        private T delegate

        T createProxy(T target){
            this.delegate = target
            Enhancer enhancer = new Enhancer()
            enhancer.setSuperclass(target.getClass())
            enhancer.setCallback(this)
            enhancer.setClassLoader(target.getClass().getClassLoader())
            return enhancer.create()
        }


        @Override
        Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            def result
            before()
            if( delegate.getClass().isInterface() ){
                result = method.getName()
            }else{
                if(method.getName() == "sayHello"){
                    result = method.invoke(delegate,objects)
                }else{
                    result = methodProxy.invokeSuper(o,objects)
                }
            }
            after(result)
        }

        void before(){
            println("之前执行")
        }

        Object after(Object result){
            println("之后执行")
            result
        }
    }

    static interface Protocol{
        String hello()
    }
}
